package cc.rengu.igas.opms.core.service.trans.common;

import cc.rengu.igas.opms.common.constant.OpmsTreeNodeConstant;
import cc.rengu.igas.opms.common.constant.OpmsParamConstant;
import cc.rengu.igas.opms.common.enums.RespCodeEnum;
import cc.rengu.igas.opms.core.service.base.PayService;
import cc.rengu.igas.opms.facade.bean.ExtraParam;
import cc.rengu.igas.opms.facade.request.GetOutPageUrlRequest;
import cc.rengu.igas.opms.facade.response.GetOutPageUrlResponse;
import cc.rengu.oltp.service.common.constant.AppParamConstant;
import cc.rengu.oltp.service.common.constant.TreeNodeConstant;
import cc.rengu.oltp.service.common.entity.ChannelCallCfg;
import cc.rengu.oltp.service.common.entity.SysParam;
import cc.rengu.oltp.service.common.enums.CheckResultEnum;
import cc.rengu.oltp.service.common.enums.TransStatusEnum;
import cc.rengu.oltp.service.model.BizException;
import cc.rengu.oltp.service.model.BizResponse;
import cc.rengu.oltp.service.model.OrderInfo;
import cc.rengu.oltp.service.realize.SysParamService;
import cc.rengu.oltp.service.realize.TransCustomImpl;
import cc.rengu.oltp.service.realize.impl.SysParamServiceImpl;
import cc.rengu.oltp.utility.util.AESUtil;
import cc.rengu.oltp.utility.util.ConvertUtil;
import cc.rengu.oltp.utility.util.XmlTreeUtil;
import org.apache.commons.codec.binary.Base64;

import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 获取外放页面url
 */
public class GetOutPageUrlService extends PayService implements TransCustomImpl {
    @Override
    protected Object bizBeforeCust() throws Exception {
        GetOutPageUrlRequest getOutPageUrlRequest = new GetOutPageUrlRequest();
        ConvertUtil.convertOutput(getOutPageUrlRequest);
        return getOutPageUrlRequest;
    }

    @Override
    protected BizResponse bizProcessCust(Object request) throws Exception {
        XmlTreeUtil xmlTreeUtil = new XmlTreeUtil();
        GetOutPageUrlRequest getOutPageUrlRequest = (GetOutPageUrlRequest) request;
        BizResponse<GetOutPageUrlResponse> bizResponse = new BizResponse<>();
        GetOutPageUrlResponse getOutPageUrlResponse = new GetOutPageUrlResponse();
        bizResponse.setRspSysId(AppParamConstant.IGAS);

        String instId = getOutPageUrlRequest.getHeader().getInstId();
        String sysSeqNum = xmlTreeUtil.getXmlTreeStringValue(TreeNodeConstant.SYS_SEQ_NUM);
        List<ExtraParam> extraParamList = getOutPageUrlRequest.getExtraParamList();

        SysParamService sysParamService = new SysParamServiceImpl();
        SysParam onlineCasherUrlParam = sysParamService.getSysParamInfo(AppParamConstant.DEFAULT_INSTID, OpmsParamConstant.OPMS_SYS_PARAM, getOutPageUrlRequest.getOutPageId());
        if (null == onlineCasherUrlParam) {
            rglog.info("法人行域名未配置，instId:<{}>", instId);
            throw new BizException(RespCodeEnum.SYSTEM_ERROR.getRespCode(), RespCodeEnum.SYSTEM_ERROR.getRespDesc());
        }

        SysParam AESKeyParam = sysParamService.getSysParamInfo(AppParamConstant.DEFAULT_INSTID, OpmsParamConstant.OPMS_SYS_PARAM, OpmsParamConstant.AES_ENC_KEY);
        if (null == AESKeyParam) {
            rglog.info("AES密钥未配置");
            throw new BizException(RespCodeEnum.SYSTEM_ERROR.getRespCode(), RespCodeEnum.SYSTEM_ERROR.getRespDesc());
        }

        List<ExtraParam> senitiveParamList = new ArrayList<>();
        List<ExtraParam> noEncParamList = new ArrayList<>();
        if (extraParamList != null && !extraParamList.isEmpty()) {
            Map<String, List<ExtraParam>> sensitiveMap = extraParamList.stream().collect(Collectors.groupingBy(ExtraParam::getSensitiveInfoFlag));
            if (sensitiveMap.get("Y") != null) {
                senitiveParamList = sensitiveMap.get("Y");
            }
            if (sensitiveMap.get("N") != null) {
                noEncParamList = sensitiveMap.get("N");
            }
        }
        /*敏感信息加密*/
        ExtraParam extraParam = new ExtraParam();
        if (getOutPageUrlRequest.getUserId() != null) {
            extraParam = new ExtraParam();
            extraParam.setParamKey(OpmsTreeNodeConstant.USER_ID);
            extraParam.setParamValue(getOutPageUrlRequest.getUserId());
            senitiveParamList.add(extraParam);
        }
        extraParam = new ExtraParam();
        extraParam.setParamKey(OpmsTreeNodeConstant.ORDER_CHANEL_ID);
        extraParam.setParamValue(getOutPageUrlRequest.getHeader().getChanlId());
        noEncParamList.add(extraParam);
        String onlineCasherUrl = generateHttpUrl(onlineCasherUrlParam.getParamValue(), AESKeyParam.getParamValue(), senitiveParamList, noEncParamList);


        getOutPageUrlResponse.setOutPageUrl(onlineCasherUrl);
        bizResponse.setRespCode(RespCodeEnum.TRANS_SUCCESS.getRespCode());
        bizResponse.setRespDesc(RespCodeEnum.TRANS_SUCCESS.getRespDesc());
        bizResponse.setResult(getOutPageUrlResponse);
        return bizResponse;
    }

    @Override
    protected void bizAfterCust(Object response) throws Exception {
        BizResponse bizResponse = (BizResponse) response;
        if (bizResponse.getResult() == null) {
            return;
        }
        GetOutPageUrlResponse getOutPageUrlResponse = (GetOutPageUrlResponse) bizResponse.getResult();
        ConvertUtil.convertOutput(getOutPageUrlResponse);
    }


    /**
     * 根据配置拼装收银台URL地址
     *
     * @param transUrl URL地址
     * @return URL地址
     */
    private String generateHttpUrl(String transUrl, String aesKey, List<ExtraParam> senitiveParamList, List<ExtraParam> noEncParamList) throws Exception {
        String requestUrlParam = "";
        String encryptDataParam = "";
        for (ExtraParam extraParam : senitiveParamList) {
            encryptDataParam += extraParam.getParamKey() + "=" + extraParam.getParamValue() + "&";
        }
        String encryptData = AESUtil.pkcs7CbcEncryptData(Base64.decodeBase64(aesKey), encryptDataParam.substring(0, encryptDataParam.length() - 1).getBytes());
        requestUrlParam += OpmsTreeNodeConstant.ENCRYPT_DATA + "=" + URLEncoder.encode(encryptData, OpmsParamConstant.UTF_8_ENCODING) + "&";
        for (ExtraParam extraParam : noEncParamList) {
            requestUrlParam += extraParam.getParamKey() + "=" + extraParam.getParamValue() + "&";
        }
        return transUrl + requestUrlParam.substring(0, requestUrlParam.length() - 1);
    }

    @Override
    public ChannelCallCfg channelCallSceneDiscern(Object request, List<ChannelCallCfg> channelCallCfgList) throws Exception {
        return null;
    }

    @Override
    public CheckResultEnum channelCallPreCheck(Object request, ChannelCallCfg channelCallCfg, OrderInfo orderInfo) throws Exception {
        return null;
    }

    @Override
    public TransStatusEnum channelCallResultProc(Object request, ChannelCallCfg channelCallCfg, TransStatusEnum transStatusEnum, Object channelResponse, OrderInfo needUpdateOrderInfo) throws Exception {
        return null;
    }
}
